﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace YFrameWork.RunTime
{

    public class ResourceManager : IResourceManager
    {
        private readonly Dictionary<uint, ResourceItem> m_ResourceItemDic = new Dictionary<uint, ResourceItem>();

        /// <summary>
        /// 资源加载
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="path"></param>
        /// <returns></returns>
        public T LoadResource<T>(string path) where T : Object
        {
            if (string.IsNullOrEmpty(path)) return null;

            uint crc = CRC32.GetCRC32(path);

            ResourceItem Item = GetCacheResourceItem(crc);

            Object obj;
            obj = Item.obj;

            if (obj != null) return obj as T;

            obj = Resources.Load<T>(path);

            CacheResource(path,ref Item, obj);

            return obj as T;
        }

        /// <summary>
        /// 资源释放
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="destoryObj"></param>
        /// <returns></returns>
        public bool ReleaseResource(Object obj, bool destoryObj = false)
        {
            if (obj==null)
            {
                Log.Error("资源加载要释放的Object为空的");
                return false; 
            }
            ResourceItem Item = null;
            foreach (var item in m_ResourceItemDic.Values)
            {
                if (item.m_Guid == obj.GetInstanceID())
                {
                    Item = item;
                }
            }

            ReleaseResource(Item, destoryObj);

            return true;
        }
        /// <summary>
        /// 释放资源
        /// </summary>
        /// <param name="item"></param>
        /// <param name="destoryObj"></param>
        /// <returns></returns>
        public bool ReleaseResource(ResourceItem item, bool destoryObj = false)
        {
            if (item == null)
            {
                Log.Error("Unfound:{0},May have been reslease.", item);
                return false;
            }
            item.RefCount--;

            DestoryResourceItem(item, destoryObj);

            return true;
        }
        /// <summary>
        /// 删除资源
        /// </summary>
        /// <param name="item"></param>
        /// <param name="destoryCache"></param>
        public void DestoryResourceItem(ResourceItem item, bool destoryCache = false)
        {
            if (!CanDestoryResourceItem(item, destoryCache))
            {
                return;
            }

            if (item.obj != null)
            {
                if (item.obj.GetType() != typeof(GameObject))
                {
                    Resources.UnloadAsset(item.obj);
                 
                }

                item.obj = null;
                Resources.UnloadUnusedAssets();
            }
        }

        /// <summary>
        /// 判断能够释放资源
        /// </summary>
        /// <param name="Item"></param>
        /// <param name="destoryCache"></param>
        /// <returns></returns>
        public bool CanDestoryResourceItem(ResourceItem Item, bool destoryCache)
        {
            if (Item == null && Item.RefCount >0)
            {
                Log.Info("要释放的这ResourceItem还在被使用", Item.Path);
                return false;
            }
            if (!destoryCache)
            {
                //m_noRefrenceAssetList.InsertToHead(item);
                return false;
            }

            if (!m_ResourceItemDic.Remove(Item.Crc))
            {
                return false;
            }

            return true;
        }


        /// <summary>
        /// 获取资源或者创建资源
        /// </summary>
        /// <param name="_crc"></param>
        /// <param name="_addrefcount"></param>
        /// <returns></returns>
        public ResourceItem GetCacheResourceItem(uint _crc, int _addrefcount = 1)
        {
            if (m_ResourceItemDic.TryGetValue(_crc, out ResourceItem _item)&&_item!=null)
            {
                _item.RefCount += _addrefcount;
                _item.m_LastUserTime = Time.realtimeSinceStartup;
             
            }
            else
            {
                _item = new ResourceItem();
                _item.Crc = _crc;
            }
            
            return _item;
        }

        /// <summary>
        /// 缓存资源
        /// </summary>
        /// <param name="_path"></param>
        /// <param name="_item"></param>
        /// <param name="_obj"></param>
        /// <param name="_addrefcount"></param>
        public void CacheResource(string _path, ref ResourceItem _item , Object _obj, int _addrefcount = 1)
        {
            if (_item == null)
            {
                Log.Error("ResourceItem is null,path:" + _path);
            }
            if (_obj == null)
            {
                Log.Error("ResourceLoad fail:" + _path);
            }
            _item.obj = _obj;
            _item.Path = _path;
            _item.m_Guid = _obj.GetInstanceID();
            _item.m_LastUserTime = Time.realtimeSinceStartup;
            _item.RefCount += _addrefcount;
            if (m_ResourceItemDic.ContainsKey(_item.Crc))
            {
                m_ResourceItemDic[_item.Crc] = _item;
            }
            else
            {
                m_ResourceItemDic.Add(_item.Crc, _item);
            }
        }
    }
}